#ifndef _UC_SEGMENT_H_
#define _UC_SEGMENT_H_

#define DATA_HEADER_LEN (sizeof(app_ps_header_t) + ASYNC_WIOTA_CRC_DATA_LEN)

typedef struct
{
    rt_slist_t node;
    unsigned char *data;
    unsigned short data_len;
    unsigned char cur_num;
    unsigned char na;
} t_data_seg;

typedef struct
{
    rt_list_t node;
    unsigned int src_addr;
    unsigned int create_packet_tick;
    unsigned char packet_num;
    unsigned char total_num;
    unsigned char cur_num;
    unsigned char is_end;
    t_data_seg *data_seg;
} t_data_packet;



/**
 * @brief package management initialization
 *
 */
void data_packet_init(void);

/**
 * @brief package management de initialization
 *
 */
void data_packet_deinit(void);

/**
 * @brief  call this interface to release data_seg after data recved and merged
 *
 * @param  data_seg: data segment
 * @param  is_free_head: free head node flag
 *
 */
void data_seg_clear(t_data_seg *data_seg, rt_bool_t is_free_head);

/**
 * @brief  call this interface to release memory after data recved and merged
 *
 * @param  data_packet: recved data packet
 *
 */
void data_packet_clear(t_data_packet *data_packet);

/**
 * @brief  call this interface to release memory after data recved and merged
 *
 * @param  data_packet: recved data packet
 *
 */

//void data_seg_clear(t_data_packet *data_packet);

/**
 * @brief period clear the data packets
 *
 */
void data_packet_period_clear(void);

/**
 * @brief according to src_addr and packet_num returns a t_data_packet structure pointer
 *
 * @param  src_addr: recved data packet
 * @param  packet_num: package No
 * @return t_data_packet structure pointer
 *
 */
t_data_packet *data_packet_append(unsigned int src_addr, unsigned char packet_num);

/**
 * @brief record data and data length in segmented information

 * @param  data_packet: t_data_packet structure pointer, call function "rr_data_packet_append" to get
 * @param  data: segmented data address
 * @param  data_len: segmented data length
 * @param  cur_seg: current segmented data number
 * @param is_end: recv end flag
 * @return 0:suc, other:fail
 *
 */
int data_seg_append(t_data_packet *data_packet, void *data, unsigned int data_len, unsigned short cur_num, unsigned char is_end);

/**
 * @brief call this interface after recving all segmented data packets, and merge all segmented data packets into a complete data packet
 *
 * @param  data_packet: t_data_packet structure pointer, call function "rr_data_packet_append" to get
 * @param  data: address of the completeed data package after merging
 * @param  data_len: length of the completeed data package after merging
 * @return 0:suc, other:fail
 *
 */
int data_seg_merge(t_data_packet *data_packet, void **data, unsigned int *data_len);

/**
 * @brief 
 *
 * @return 0:no segment, 1: continue differentical packets, 
        2: end differentical packets; 3: fail.
 *
 */
int packege_segment_parsing(void *header, void *in_data, unsigned int in_data_len, void **out_data, unsigned int *data_len, void **page);


#endif
